package org.apache.jena.query.spatial;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.hpl.jena.graph.Node;

public class SpatialPredicatePairValue {

	private static Logger log = LoggerFactory
			.getLogger(SpatialPredicatePairValue.class);

	public SpatialPredicatePairValue(SpatialPredicatePair pair) {
		this.pair = pair;
	}

	private SpatialPredicatePair pair;
	private Double latitudeValue;
	private Double longitudeValue;

	public Double getLatitudeValue() {
		return latitudeValue;
	}

	public Double getLongitudeValue() {
		return longitudeValue;
	}

	public SpatialPredicatePair getPair() {
		return pair;
	}

	public void setValue(Node predicate, Double value) {
		if (predicate.equals(pair.getLatitudePredicate())) {
			this.latitudeValue = value;
		} else if (predicate.equals(pair.getLongitudePredicate())) {
			this.longitudeValue = value;
		} else {
			log.warn("Try to set value to a SpatialPredicatePairValue with no such predicate: "
					+ predicate + " :: " + value);
		}

	}

	public Double getTheOtherValue(Node predicate) {
		if (pair.getLatitudePredicate().equals(predicate)) {
			return this.getLongitudeValue();
		} else if (predicate.equals(pair.getLongitudePredicate())) {
			return this.getLatitudeValue();
		} else {
			log.warn("Try to get value to a SpatialPredicatePairValue with no such predicate: "
					+ predicate);
			return null;
		}
	}

	@Override
	public int hashCode() {
		int latitudeHashCode = latitudeValue == null ? 0 : latitudeValue
				.hashCode() * 17;
		int longitudeHashCode = longitudeValue == null ? 0 : longitudeValue
				.hashCode() * 19;
		return pair.hashCode() * 11 + latitudeHashCode + longitudeHashCode;
	}

	@Override
	public boolean equals(Object otherObject) {
		// a quick test to see if the objects are identical
		if (this == otherObject)
			return true;

		// must return false if the explicit parameter is null
		if (otherObject == null)
			return false;

		// if the classes don't match, they can't be equal
		if (getClass() != otherObject.getClass())
			return false;

		// now we know otherObject is a non-null Employee
		SpatialPredicatePairValue other = (SpatialPredicatePairValue) otherObject;

		boolean latitudeValueEquals = this.latitudeValue == null ? other.latitudeValue == null
				: this.latitudeValue.equals(other.latitudeValue);
		boolean longitudeValueEquals = this.longitudeValue == null ? other.longitudeValue == null
				: this.longitudeValue.equals(other.longitudeValue);

		// test whether the fields have identical values
		return pair.equals(other.pair) && latitudeValueEquals
				&& longitudeValueEquals;
	}

	public static void main(String... strings) {
		SpatialPredicatePair pair1 = new SpatialPredicatePair(
				EntityDefinition.geo_latitude.asNode(),
				EntityDefinition.geo_longitude.asNode());
		SpatialPredicatePair pair2 = new SpatialPredicatePair(
				EntityDefinition.geo_latitude.asNode(),
				EntityDefinition.geo_longitude.asNode());
		System.out.println(pair1.equals(pair2));
		System.out.println(pair1.hashCode() == pair2.hashCode());

		SpatialPredicatePairValue value1 = new SpatialPredicatePairValue(pair1);
		value1.setValue(EntityDefinition.geo_latitude.asNode(), 12.0);
		value1.setValue(EntityDefinition.geo_longitude.asNode(), 23.0);

		SpatialPredicatePairValue value2 = new SpatialPredicatePairValue(pair2);
		value2.setValue(EntityDefinition.geo_latitude.asNode(), 12.0);
		value2.setValue(EntityDefinition.geo_longitude.asNode(), 23.0);

		System.out.println(value1.equals(value2));
		System.out.println(value1.hashCode() == value2.hashCode());
		
		value1.setValue(EntityDefinition.geo_latitude.asNode(),null);
		value2.setValue(EntityDefinition.geo_latitude.asNode(),null);
		
		System.out.println(value1.equals(value2));
		System.out.println(value1.hashCode() == value2.hashCode());
		
		value2.setValue(EntityDefinition.geo_latitude.asNode(),23.0);
		System.out.println(value1.equals(value2));
		System.out.println(value1.hashCode() == value2.hashCode());
	}
}
